<?php
/**
 * 管易API接口
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/8/30/030
 * Time: 下午 2:41
 */
namespace app\service;

use sendmsg\Sms;
use think\Db;
use think\Env;
use think\Exception;

class GuanyiService
{
    //订单查询 API
    const   INVOICE_QUERY_API = 'gy.erp.trade.get';
    const   GUANYI_SYNC_DELIVER_USER    =   'GuanYiSyncApi';

    private $sysParams = [];                                    #系统级参数集合
    private $appkey = '120086';
    private $sessionkey = 'd45985bd7d58413c807752f57f7b27d9';   #正式
    private $apiurl = 'http://v2.api.guanyierp.com/rest/erp_open'; #正式api地址
    private $secret = 'be7ec637ff994416938381d0fcbc3c41';       #正式
    #private $warehouseCode = '001';                             #仓库代码
    private $warehouseCode = '';                             #仓库代码

    //新管易系统,佳皿公司旗下的各供应商ID代码
    private $_platStoreNum = '01';  #平台直营,e驾优选直营供应商
    private $_langStoreNum = '02';  #郎酒品牌店
    private $_fengStoreNum = '03';  #丰谷酒业品牌旗舰店
    //v2环境，ERP的支付方式 支付宝、网银在线、财付通、邮局汇款、货到付款、现金支付、微信支付、预存款、银联支付、礼品卡
    private $tom_erp_pay = ['zfb'=>'zhifubao','wy'=>'wangyin','cft'=>'caifutong','hk'=>'huikuan','cod'=>'cod','cash'=>'cash','wx'=>'weixin','balance'=>'balance','yl'=>'yinlian','gc'=>'giftcard'];
    //目前 佳皿管易后台，支持的物流。【邮政小包,中通快递】
    private $express_code= ['yz'=>'YZXB','zt'=>'ZTO'];
    //管易同步物流API，返回的物流编号 ==> 转化平台物流公司ID编号
    private $guanyi_return_express_code = ['JDKD'=>'48','YZXB'=>'42'];

    /**
     * 获取管易物流发货信息。并同步至e驾优选平台
     * @param int $orderId              需要同步物流单号的订单ID编号
     * @param string $guanyiOrderCode   同步管易后，管易产生的编号：格式--SO182037259920
     * @return array
     */
    public function getInvoiceInfo($orderId = 0,$guanyiOrderCode = '')
    {
        //传入order_id，根据order_id获取 同步管易后的订单号：例子--SO182037259920
        $questParams = [
            "code" => $guanyiOrderCode,
        ];
        $lists = $this->questGuanyi(self::INVOICE_QUERY_API,$questParams);

        if(empty($lists))   return ['success'=>'false','errorDesc'=>'Guanyi Return Null !'];
        $order_model = model('order');
        $condition = array();
        $condition['order_id'] = $orderId;
        $orderInfo = $order_model->getOrderInfo($condition, array('order_common', 'order_goods'));

        if(empty($orderInfo))   return ['success'=>'false','errorDesc'=>'Not Fount OrderInfo!'];
        //当前订单已发货的，不能重复调用
        if(!empty($orderInfo['shipping_code'])) return ['success'=>'false','errorDesc'=>'Order Has Shipped!'];
        if(!empty($lists)){
            //获取当前管易订单的 deliverys
            $deliverys  = isset($lists['orders'][0]['deliverys']) ? $lists['orders'][0]['deliverys'] : [];

            if(empty($deliverys))   return ['success'=>'false','errorDesc'=>'Not Found DeliverInfo!'];
            //物流公司代号
            $expressCode= isset($deliverys[0]['express_code']) ? $deliverys[0]['express_code'] : '';
            //快递单号
            $expressNum = isset($deliverys[0]['mail_no']) ? $deliverys[0]['mail_no'] : '';
            //如果快递单号为空，提示暂未获取到物流信息
            if(empty($expressNum))  return ['success'=>'false','errorDesc'=>'No logistics information available！'];

            $express = rkcache('express', true);
            //转化为e驾优选平台对应的： shipping_express_id
            $shipping_express_id = isset($this->guanyi_return_express_code[$expressCode]) ? $this->guanyi_return_express_code[$expressCode] : '';

            if(empty($shipping_express_id)) return ['success'=>'false','errorDesc'=>'ExpressCode Not In JDKD|YZXB !'];
            //组装订单发货所需数据
            $extend_order_common = $orderInfo['extend_order_common'];

            $post = [
                'daddress_id'   => $extend_order_common['daddress_id'],
                'reciver_name'  => $extend_order_common['reciver_name'],
                'reciver_info'  => serialize($extend_order_common['reciver_info']),
                'reciver_area'  => str_replace(' ', '+', $extend_order_common['reciver_info']['area']),    #使用+号链接
                'reciver_street'=> $extend_order_common['reciver_info']['street'],
                'shipping_code' => $expressNum, #物流单号
                'reciver_mob_phone' => $extend_order_common['reciver_info']['mob_phone'],
                'reciver_tel_phone' => '',
                'deliver_explain'   => $extend_order_common['order_message'],
                'shipping_express_id' => $shipping_express_id,
            ];

            return  $this->_exec_seller_deliver($orderInfo,$post);
        }
    }

    /**
     * 执行供应商端发货操作
     * @param array $orderInfo  订单信息
     * @param array $post       模拟供应商端发货所需数据
     */
    private function _exec_seller_deliver($orderInfo = [],$post = [])
    {
        try{
            //执行供应商端的发货操作
            $logic_order = model('order','logic');
            $result = $logic_order->changeOrderSend($orderInfo, 'seller', self::GUANYI_SYNC_DELIVER_USER, $post);

            if (!$result['code']) return ['success'=>'false','errorDesc'=>'OrderSn：'.$orderInfo['order_sn'].'==>'.$result['msg']];
            //正式环境才需发送短信
            if(!Env::get('global_config.app_debug')){
                //发送 订单发货短信
                $orderSn = $orderInfo['order_sn']; #订单编号
                $mobile  = $orderInfo['extend_order_common']['reciver_info']['mob_phone']; #收货人手机号
                #物流单位
                $shipping_express_id = $post['shipping_express_id'];
                #如果无需物流发货，下面流程可以终止
                if($shipping_express_id == 'e1000') return ['success'=>'false','errorDesc'=>'OrderSn：'.$orderInfo['order_sn'].'==>'.$result['msg']];

                $express = rkcache('express', true);
                $express_name = $express[$shipping_express_id]['express_name'];
                $logisticsCompany = empty($express_name) ? config('default_logistics') : $express_name;    #没有则展示默认物流单位

                $logisticsNumber  = isset($post['shipping_code']) ? $post['shipping_code'] : '';         #物流单号
                $content = config('sms_extra_template.send_order_deliver'); #订单发货模板消息

                $sendMsg = sprintf($content,$orderSn,$logisticsCompany,$logisticsNumber);
                (new Sms())->send($mobile,$sendMsg);
            }

            return ['success'=>'success','errorDesc'=>''];
        }catch (Exception $e){
            return ['success'=>'false','errorDesc'=>$e->getMessage()];
        }
    }

    /**
     * 请求管易接口
     * @param string $method    管易API方法
     * @param array $argParams  请求参数
     * @param int $orderId      订单ID编号
     * @return array|mixed
     */
    public function questGuanyi($method = '',$argParams = [],$orderId = 0)
    {
        $this->sysParams['appkey']  = $this->appkey;
        $this->sysParams['method']  = $method;
        $this->sysParams['sessionkey'] = $this->sessionkey;
        //整合请求参数
        if(!empty($argParams))  foreach ($argParams as $key=>$val)  $this->sysParams[$key] = $val;
        //转换为json对象【管易的坑，不能将中文一起转换】
        $jsonObj = $this->_json_encode_ch($this->sysParams);
        //获取sign签名
        $this->sysParams['sign'] = $this->getSign($jsonObj);
        //开始请求API
        $res = http_json_post($this->apiurl,$this->_json_encode_ch($this->sysParams));
        $arr = json_decode($res,true);

        return $arr;
    }
    /**
     * 组合请求API的参数
     * @param string $method    请求的API地址
     * @param string $sign      当前请求的sign验签
     * @param array $argParams  当前API，应用级参数
     */
    public function questGuanyiApi($method = '',$argParams = [],$orderId = 0)
    {

        $this->sysParams['appkey']  = $this->appkey;
        $this->sysParams['method']  = $method;
        $this->sysParams['sessionkey'] = $this->sessionkey;
        //整合请求参数
        if(!empty($argParams))  foreach ($argParams as $key=>$val)  $this->sysParams[$key] = $val;
        //转换为json对象【管易的坑，不能将中文一起转换】
        $jsonObj = $this->_json_encode_ch($this->sysParams);
        //获取sign签名
        $this->sysParams['sign'] = $this->getSign($jsonObj);
        //开始请求API
        $res = http_json_post($this->apiurl,$this->_json_encode_ch($this->sysParams));
        $arr = json_decode($res,true);
        //添加同步日志
        try{
            $insertData = [
                'order_id'  => $orderId,
                'error_code'=> $arr['success'] != false ? 'success' : 'false',
                'token_code'=> !empty($arr['code']) ? $arr['code'] : '',
                'error_desc'=> $arr['errorDesc'] != ""  ? $arr['errorDesc'] : 'success',
                'created'   => !empty($arr['created'])  ? $arr['created']  : '',
            ];
            $this->addOrderSyncLog($insertData);
        }catch (Exception $e){
            return ['success'=>false,'errorDesc'=>$e->getMessage()];
        }

        return $arr;
    }

    /**
     * 获取订单同步至管易的记录【表：ds_sync_order_guanyi_log】
     * @param int $orderId  订单ID编号
     */
    public function getOrderSyncGuanyiRow($condition = [],$field = '*')
    {
        return  Db::name('sync_order_guanyi_log')->where($condition)->field($field)->select();
    }
    /**
     * 获取单条订单同步至管易的记录【表：ds_sync_order_guanyi_log】
     * @param int $orderId  订单ID编号
     */
    public function getOrderSyncGuanyiItem($condition = [],$field = '*')
    {
        return  Db::name('sync_order_guanyi_log')->where($condition)->field($field)->find();
    }
    /**
     * 新增订单同步管易的log日志记录
     * @param array $data   数据表数据
     */
    public function addOrderSyncLog($data = [])
    {
        return  Db::name('sync_order_guanyi_log')->insert($data);
    }
    /**
     * json中文转换
     * @param $var      需转换的数据Data
     * @return string   最终转换的字符串
     */
    private function _json_encode_ch($var)
    {
        return urldecode(json_encode($this->_url_encode_arr($var)));
    }

    /**
     * 转义中文字符串
     * @param $arr      数据数组
     * @return array|string
     */
    private function _url_encode_arr($arr)
    {
        if (is_array($arr)) {
            foreach ($arr as $k => $v) {
                $arr[$k] = $this->_url_encode_arr($v);
            }
        } elseif (!is_numeric($arr) && !is_bool($arr)) {
            $arr = urlencode($arr);
        }
        return $arr;
    }
    /**
     * 获取sign签名
     * @param $params   请求参数
     * @return string   返回md5加密字符串
     */
    protected function getSign($jsonParams = '')
    {
        return strtoupper(md5($this->secret.$jsonParams .$this->secret));
    }

    /**
     * 同步订单至管易
     * @param array $argsData       普通请求参数
     * @param array $itemData       商品明细参数
     * @param array $paymentData    支付相关参数
     * @param array $invoiceData    发票相关参数
     * @param array $orderTypeCode  订单类型：【Sales-销售订单、Return-换货订单、Charge-费用订单、Delivery-补发货订单、Invoice-补发票订单】
     */
    public function orderToErpAdd($argsData = [],$itemData = [],$paymentData = [],$invoiceData = [],$orderTypeCode = 'Sales')
    {
        try{
            $toErpData = [];
            $orderId = isset($argsData['order_id']) && !empty($argsData['order_id']) ? $argsData['order_id'] : 0; #当前同步的订单ID编号

            if(empty($orderId)) return ['success'=>false,'errorDesc'=>lang('order_id_err')];
            //查询当前订单是否，同步过管易
            $syncOrderInfo = $this->getOrderSyncGuanyiRow(['order_id'=>$orderId,'error_code'=>'success'],'id,token_code');
            if(!empty($syncOrderInfo[0]['id']))   return ['success'=>false,'errorDesc'=>lang('order_id_err')];

            $toErpData['shop_code'] = isset($argsData['shop_code']) && !empty($argsData['shop_code']) ? $argsData['shop_code'] : $this->_platStoreNum;  #供应商代码
            $toErpData['vip_code']  = isset($argsData['vip_code']) && !empty($argsData['vip_code'])   ? $argsData['vip_code']  : $argsData['receiver_mobile'];  #用户唯一凭证，使用手机号

            $toErpData['deal_datetime']     = isset($argsData['deal_datetime']) && !empty($argsData['deal_datetime']) ? date('Y-m-d H:i:s',$argsData['deal_datetime']) : 0;  #订单下单时间
            $toErpData['receiver_name']     = isset($argsData['receiver_name']) && !empty($argsData['receiver_name']) ? $argsData['receiver_name'] : '';  #订单收货人
            $toErpData['receiver_mobile']   = isset($argsData['receiver_mobile']) && !empty($argsData['receiver_mobile']) ? $argsData['receiver_mobile'] : '';  #订单收货人手机号
            $toErpData['receiver_province'] = isset($argsData['receiver_province']) && !empty($argsData['receiver_province']) ? $argsData['receiver_province'] : '';  #订单收货人所在省
            $toErpData['receiver_city']     = isset($argsData['receiver_city']) && !empty($argsData['receiver_city']) ? $argsData['receiver_city'] : '';  #订单收货人所在市级
            $toErpData['receiver_district'] = isset($argsData['receiver_district']) && !empty($argsData['receiver_district']) ? $argsData['receiver_district'] : '';  #订单收货人所在区、县级
            $toErpData['receiver_address']  = isset($argsData['receiver_address']) && !empty($argsData['receiver_address']) ? $argsData['receiver_address'] : '';  #订单收货人具体地址
            $toErpData['buyer_memo']        = isset($argsData['buyer_memo']) && !empty($argsData['buyer_memo']) ? $argsData['buyer_memo'] : 'e驾优选,用户下单备注！';  #当前订单买家留言

            $toErpData['warehouse_code']    = $this->warehouseCode;    #仓库代码
            $toErpData['order_type_code']   = $orderTypeCode;          #订单下单时间
            #$toErpData['express_code']     = $this->express_code['yz'];   #目前佳皿指定，邮政小包
            $toErpData['express_code']      = '';    #目前管易已经能自动匹配物流
            //商品明细
            $toErpData['details'] = [];
            if(!empty($itemData)){
                foreach ($itemData as $k=>$row){
                    $toErpData['details'][$k]['item_code']  = isset($row['item_code']) && !empty($row['item_code']) ? $row['item_code'] : '';   #管易对应的商品代码
                    $toErpData['details'][$k]['price']      = isset($row['price']) && !empty($row['price']) ? $row['price'] : 0;    #商品金额
                    $toErpData['details'][$k]['qty']        = isset($row['qty']) && !empty($row['qty']) ? $row['qty'] : 0;          #购买的商品数量
                }
            }
            //支付明细【一个订单就一种支付方式,为满足API需求，增加0的索引】
            $toErpData['payments'][0]['pay_type_code'] = $this->tom_erp_pay[$paymentData['pay_type_code']]; #支付方式：zfb、wy等
            $toErpData['payments'][0]['payment'] = $paymentData['payment'];    #订单支付金额

            //TODO：处理发票【暂不支持发票开票】
            //$toErpData['invoices'] = [];
            //发送同步订单新增API
            return  $this->questGuanyiApi('gy.erp.trade.add',$toErpData,$orderId);
        }catch (Exception $e){
            return ['success'=>false,'errorDesc'=>$e->getMessage()];
        }
    }
}